# -*- coding: utf-8 -*-
# @Time    : 2019/11/1 8:49
# @Author  : 岳保保
# @File    : rest.py
# @Software: PyCharm
from django.db import transaction
from django.db.models import Q, QuerySet
from django.urls import path
from rest_framework.views import APIView

from utils.middleware.CustomException import CustomException
from utils.utils.ResultResponse import Success, CommonResponse, QueryResponse


class RestAPIView(APIView):
    model_class = None
    request_verify_class = None
    response_serializer_class = None
    url_path = None
    api_tags = None

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        if not self.model_class:
            raise Exception("%s的model_class未定义" % (str(self)))
        if not self.request_verify_class:
            raise Exception("%s的request_verify_class未定义" % (str(self)))
        if not self.response_serializer_class:
            raise Exception("%s的response_serializer_class未定义" % (str(self)))

    @transaction.atomic
    def post(self, request):
        """添加"""
        request_verify_form = self.request_verify_class(request.data)
        if request_verify_form.is_valid():
            valid_data = request_verify_form.get_valid_data()

            # 取出多对多的关系
            queryset = {
                item: valid_data[item]
                for item in valid_data
                if isinstance(valid_data[item], QuerySet)
            }

            # 剔除多对多关系
            for item in queryset:
                del valid_data[item]

            # 保存对象
            obj = self.model_class.objects.create(**valid_data)

            # 保存多对多关系
            for item in queryset:
                if hasattr(obj, item):
                    attr = getattr(obj, item)
                    attr.set(queryset[item])
                else:
                    raise CustomException("该对象没有属性%s" % item)
            return Success()
        else:
            raise CustomException(data=request_verify_form.errors)

    @transaction.atomic
    def put(self, request):
        """修改"""
        print("121212")
        obj_id = request.data.get("pk")
        obj = self.model_class.objects.get(pk=obj_id)
        request_verify_form = self.request_verify_class(request.data, instance=obj)
        if request_verify_form.is_valid():

            valid_data = request_verify_form.get_valid_data()
            # 取出多对多的关系
            queryset = {
                item: valid_data[item]
                for item in valid_data
                if isinstance(valid_data[item], QuerySet)
            }

            # 剔除多对多关系
            for item in queryset:
                del valid_data[item]

            # 保存对象
            self.model_class.objects.filter(pk=obj_id).update(**valid_data)

            # 更改多对多关系
            for item in queryset:
                if hasattr(obj, item):
                    attr = getattr(obj, item)
                    attr.set(queryset[item])
                else:
                    raise CustomException("该对象没有属性%s" % item)
        else:
            raise CustomException(data=request_verify_form.errors)
        return Success()

    def condition_search_filter(self, request):
        """
        构建条件查询
        :param request:
        :return: 必须return Q函数对象
        """
        return Q()

    def get(self, request):
        """查看"""
        obj_id = request.data.get("pk")
        if obj_id:
            obj = self.model_class.objects.get(pk=obj_id)
            return CommonResponse(model=obj, serializer=self.response_serializer_class)
        else:
            return QueryResponse(queryset=self.model_class.objects.filter(self.condition_search_filter(request)),
                                 serializer=self.response_serializer_class,
                                 request=request, view=self)

    def condition_delete_filter(self, request):
        """构建条件删除"""
        return Q()

    @transaction.atomic
    def delete(self, request):
        """删除"""
        obj_id = request.data.get("pk")
        if obj_id:
            self.model_class.objects.filter(pk=obj_id).delete()
        else:
            self.model_class.objects.filter(self.condition_delete_filter(request)).delete()
        return Success()

    @classmethod
    def register(cls):
        url_pattern = path(cls.url_path, cls.as_view())
        url_pattern.__dict__['view_class'] = cls
        return url_pattern
